﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Commands.Settings;
using Uploaders;

namespace Commands
{
    internal static class UploaderManager
    {
        static UploaderManager()
        {
            var settings = Settings.SettingsHelper.Settings.SharingServices;

            _dictionary = new Dictionary<SharingServices, IUploader>();

            foreach (SharingServices type in Enum.GetValues(typeof(SharingServices)))
                _CreateUploaderWithWrapping(type, settings);

            _DetectDefaultUploader(settings.DefaultServiceName);
        }

        /// <summary>
        /// Create uploader with specified type and then add it to dict.
        /// </summary>
        private static void _CreateUploaderWithWrapping(SharingServices serviceType,
            FileSharingServicesSettings settings)
        {
            try
            {
                ServiceSettings uploaderSettings = settings.GetSettingsByType(serviceType);
                _dictionary.Add(serviceType,
                    Uploaders.UploaderManager.CreateUploader(serviceType, uploaderSettings));
            }
            catch
            { 

            }
        }

        public static IEnumerable<string> UploadFile(string file, SharingServices? service,
            int size, string password, bool nozip)
        {
            Debug.Assert(file != null);

            var filePaths = new List<string>();

            var uploader = _GetService(service);

            if (nozip)
                filePaths.Add(file);
            else
                filePaths.AddRange(Zipper.ZipFile(file, Math.Min(size, uploader.MaxFileSize), password));

            return uploader.UploadMultipeFiles(filePaths);
        }

        /// <summary>
        /// Upload folder to sharing service.
        /// </summary>
        /// <param name="directory">Directory to upload.</param>
        /// <param name="service">Service to upload.</param>
        /// <param name="size"></param>
        /// <param name="password"></param>
        /// <param name="noZip">If 'true' - folder will be uploaded non zipped, only files from top 
        /// folder will be uploaded, no files form subdir. Files which size is more 
        /// that allowed by service - will be skipped.
        /// <returns></returns>
        // TODO does it make a sense return Dict<filepath, fileurl> ??? 
        // Yeah, - redo.
        public static IEnumerable<string> UploadFolder(string directory, SharingServices? service,
            int size, string password, bool noZip)
        {
            Debug.Assert(directory != null);

            var filePaths = new List<string>();

            var uploader = _GetService(service);

            if (noZip)
                filePaths.AddRange(Directory.GetFiles(directory));
            else
                filePaths.AddRange(Zipper.ZipFolder(directory, Math.Min(size, uploader.MaxFileSize), password));

            return uploader.UploadMultipeFiles(filePaths);
        }

        // TC
        internal static string UploadFile(string filePath, SharingServices? service)
        {
            Debug.Assert(!String.IsNullOrEmpty(filePath), "filePath is null or empty.");

            foreach (var uploader in _dictionary.Values)
            {
                var path = uploader.UploadFile(filePath);
            }
            return null;
        }

        #region Private members

        private static IUploader _GetService(SharingServices? service)
        {
            if (service != null)
                return _dictionary[(SharingServices)service];
            else
                return _defaultUploader;
        }

        private static void _DetectDefaultUploader(string name)
        {
            SharingServices service;
            if (Enum.TryParse<SharingServices>(name, true, out service))
            {
                if (_dictionary.ContainsKey(service))
                    _defaultUploader = _dictionary[service];
            }

            _defaultUploader = _dictionary.Values.FirstOrDefault();
        }

        private static Dictionary<SharingServices, IUploader> _dictionary;
        private static IUploader _defaultUploader;

        #endregion
    }
}